package com.leetcode.partition5;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author `RKC`
 * @date 2022/2/18 10:33
 */
public class LC493翻转对_线段树 {

    private static final int N = 50010 * 2;
    private static Node[] tr = new Node[N << 2];
    private static Set<Long> set = new TreeSet<>();
    private static Map<Long, Integer> map = new HashMap<>(N);
    private static int n = 0;

    private static final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    private static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        String[] ss = reader.readLine().split(" ");
        int[] nums = new int[ss.length];
        for (int i = 0; i < ss.length; i++) nums[i] = Integer.parseInt(ss[i]);
        writer.write(reversePairs(nums) + "\n");
        writer.flush();
    }

    public static int reversePairs(int[] nums) {
        n = nums.length;
        //离散化
        for (int i = 0; i < n; i++) {
            set.add((long) nums[i] - 1);
            set.add(nums[i] * 2L);
        }
        int idx = 0, ans = 0;
        for (long num : set) map.put(num, ++idx);
        build(1, 1, map.size());
        // i < j, nums[i] > 2*nums[j] => nums[i]/2 > nums[j]
        for (int i = n - 1; i >= 0; i--) {
            int val = map.get((long) nums[i] - 1);
            ans += query(1, 1, val);
            modify(1, map.get(nums[i] * 2L), 1);
        }
        return ans;
    }

    private static int query(int u, int l, int r) {
        if (l <= tr[u].l && r >= tr[u].r) return tr[u].val;
        int mid = tr[u].l + tr[u].r >> 1, res = 0;
        if (l <= mid) res = query(u << 1, l, r);
        if (r > mid) res += query(u << 1 | 1, l, r);
        return res;
    }

    private static void modify(int u, int x, int k) {
        if (tr[u].l == x && tr[u].r == x) tr[u].val += k;
        else {
            int mid = tr[u].l + tr[u].r >> 1;
            if (x <= mid) modify(u << 1, x, k);
            else modify(u << 1 | 1, x, k);
            pushup(u);
        }
    }

    private static void pushup(int u) {
        tr[u].val = tr[u << 1].val + tr[u << 1 | 1].val;
    }

    private static void build(int u, int l, int r) {
        tr[u] = new Node(l, r);
        if (l != r) {
            int mid = l + r >> 1;
            build(u << 1, l, mid);
            build(u << 1 | 1, mid + 1, r);
            pushup(u);
        }
    }

    private static class Node {
        private int l, r;
        private int val;

        public Node(int l, int r) {
            this.l = l;
            this.r = r;
        }

        public Node(int l, int r, int val) {
            this.l = l;
            this.r = r;
            this.val = val;
        }
    }
}
